home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / X11R4 / cmds / X / os / 4.2bsd / xdmauth.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-12-16  |  8.4 KB  |  391 lines

  1. /*
  2.  * XDM-AUTHENTICATION-1 (XDMCP authentication) and
  3.  * XDM-AUTHORIZATION-1 (client authorization) protocols
  4.  *
  5.  * $XConsortium: xdmauth.c,v 1.2 89/12/15 20:10:17 keith Exp $
  6.  *
  7.  * Copyright 1988 Massachusetts Institute of Technology
  8.  *
  9.  * Permission to use, copy, modify, and distribute this software and its
  10.  * documentation for any purpose and without fee is hereby granted, provided
  11.  * that the above copyright notice appear in all copies and that both that
  12.  * copyright notice and this permission notice appear in supporting
  13.  * documentation, and that the name of M.I.T. not be used in advertising or
  14.  * publicity pertaining to distribution of the software without specific,
  15.  * written prior permission.  M.I.T. makes no representations about the
  16.  * suitability of this software for any purpose.  It is provided "as is"
  17.  * without express or implied warranty.
  18.  *
  19.  * Author:  Keith Packard, MIT X Consortium
  20.  */
  21.  
  22. #include "X.h"
  23. #include "os.h"
  24.  
  25. #ifdef HASDES
  26.  
  27. #ifdef XDMCP
  28. #include "Xmd.h"
  29. #include "Xdmcp.h"
  30.  
  31. /* XDM-AUTHENTICATION-1 */
  32.  
  33. static XdmAuthKeyRec    privateKey;
  34. static char XdmAuthenticationName[] = "XDM-AUTHENTICATION-1";
  35. #define XdmAuthenticationNameLen (sizeof XdmAuthenticationName - 1)
  36. static XdmAuthKeyRec    rho;
  37.  
  38. static Bool XdmAuthenticationValidator (privateData, incomingData, packet_type)
  39.     ARRAY8Ptr    privateData, incomingData;
  40.     xdmOpCode    packet_type;
  41. {
  42.     XdmAuthKeyPtr    incoming;
  43.  
  44.     XdmcpDecrypt (incomingData->data, &privateKey,
  45.                   incomingData->data,incomingData->length);
  46.     switch (packet_type)
  47.     {
  48.     case ACCEPT:
  49.         if (incomingData->length != 8)
  50.         return FALSE;
  51.         incoming = (XdmAuthKeyPtr) incomingData->data;
  52.         XdmcpDecrementKey (incoming);
  53.         return XdmcpCompareKeys (incoming, &rho);
  54.     }
  55.     return FALSE;
  56. }
  57.  
  58. static Bool
  59. XdmAuthenticationGenerator (privateData, outgoingData, packet_type)
  60.     ARRAY8Ptr    privateData, outgoingData;
  61.     xdmOpCode    packet_type;
  62. {
  63.     outgoingData->length = 0;
  64.     outgoingData->data = 0;
  65.     switch (packet_type)
  66.     {
  67.     case REQUEST:
  68.     if (XdmcpAllocARRAY8 (outgoingData, 8))
  69.         XdmcpEncrypt (&rho, &privateKey, outgoingData->data, 8);
  70.     }
  71.     return TRUE;
  72. }
  73.  
  74. static Bool
  75. XdmAuthenticationAddAuth (name_len, name, data_len, data)
  76.     int        name_len, data_len;
  77.     char    *name, *data;
  78. {
  79.     XdmcpDecrypt (data, &privateKey, data, data_len);
  80.     AddAuthorization (name_len, name, data_len, data);
  81. }
  82.  
  83. XdmAuthenticationInit (cookie, cookie_len)
  84.     char    *cookie;
  85.     int        cookie_len;
  86. {
  87.     bzero (privateKey.data, 8);
  88.     if (cookie_len > 7)
  89.     cookie_len = 7;
  90.     bcopy (cookie, privateKey.data + 1, cookie_len);
  91.     XdmcpGenerateKey (&rho);
  92.     XdmcpRegisterAuthentication (XdmAuthenticationName, XdmAuthenticationNameLen,
  93.                  &rho,
  94.                  sizeof (rho),
  95.                  XdmAuthenticationValidator,
  96.                  XdmAuthenticationGenerator,
  97.                  XdmAuthenticationAddAuth);
  98. }
  99.  
  100. #endif /* XDMCP */
  101.  
  102. /* XDM-AUTHORIZATION-1 */
  103. typedef struct _XdmAuthorization {
  104.     struct _XdmAuthorization    *next;
  105.     XdmAuthKeyRec        rho;
  106.     XdmAuthKeyRec        key;
  107.     XID                id;
  108. } XdmAuthorizationRec, *XdmAuthorizationPtr;
  109.  
  110. XdmAuthorizationPtr xdmAuth;
  111.  
  112. typedef struct _XdmClientAuth {
  113.     struct _XdmClientAuth   *next;
  114.     XdmAuthKeyRec        rho;
  115.     char            client[6];
  116.     long            time;
  117. } XdmClientAuthRec, *XdmClientAuthPtr;
  118.  
  119. XdmClientAuthPtr    xdmClients;
  120. static long        clockOffset;
  121. static Bool        gotClock;
  122.  
  123. #define TwentyMinutes    (20 * 60)
  124.  
  125. static Bool
  126. XdmClientAuthCompare (a, b)
  127.     XdmClientAuthPtr    a, b;
  128. {
  129.     int    i;
  130.  
  131.     if (!XdmcpCompareKeys (&a->rho, &b->rho))
  132.     return FALSE;
  133.     for (i = 0; i < 6; i++)
  134.     if (a->client[i] != b->client[i])
  135.         return FALSE;
  136.     return a->time == b->time;
  137. }
  138.  
  139. static
  140. XdmClientAuthDecode (plain, auth)
  141.     char        *plain;
  142.     XdmClientAuthPtr    auth;
  143. {
  144.     int        i, j;
  145.  
  146.     j = 0;
  147.     for (i = 0; i < 8; i++)
  148.     {
  149.     auth->rho.data[i] = plain[j];
  150.     ++j;
  151.     }
  152.     for (i = 0; i < 6; i++)
  153.     {
  154.     auth->client[i] = plain[j];
  155.     ++j;
  156.     }
  157.     auth->time = 0;
  158.     for (i = 0; i < 4; i++)
  159.     {
  160.     auth->time = (auth->time << 8) | (plain[j] & 0xff);
  161.     j++;
  162.     }
  163. }
  164.  
  165. XdmClientAuthTimeout (now)
  166.     long    now;
  167. {
  168.     XdmClientAuthPtr    client, next, prev;
  169.  
  170.     prev = 0;
  171.     for (client = xdmClients; client; client=next)
  172.     {
  173.     next = client->next;
  174.     if (abs (now - client->time) > TwentyMinutes)
  175.     {
  176.         if (prev)
  177.         prev->next = next;
  178.         else
  179.         xdmClients = next;
  180.         xfree (client);
  181.     }
  182.     else
  183.         prev = client;
  184.     }
  185. }
  186.  
  187. static XdmClientAuthPtr
  188. XdmAuthorizationValidate (plain, length, rho)
  189.     char        *plain;
  190.     int            length;
  191.     XdmAuthKeyPtr    rho;
  192. {
  193.     XdmClientAuthPtr    client, existing;
  194.     long        now;
  195.  
  196.     if (length != (192 / 8))
  197.     return NULL;
  198.     client = (XdmClientAuthPtr) xalloc (sizeof (XdmClientAuthRec));
  199.     if (!client)
  200.     return NULL;
  201.     XdmClientAuthDecode (plain, client);
  202.     if (!XdmcpCompareKeys (&client->rho, rho))
  203.     {
  204.     xfree (client);
  205.     return NULL;
  206.     }
  207.     now = time(0);
  208.     if (!gotClock)
  209.     {
  210.     clockOffset = client->time - now;
  211.     gotClock = TRUE;
  212.     }
  213.     now += clockOffset;
  214.     XdmClientAuthTimeout (now);
  215.     if (abs (client->time - now) > TwentyMinutes)
  216.     {
  217.     xfree (client);
  218.     return NULL;
  219.     }
  220.     for (existing = xdmClients; existing; existing=existing->next)
  221.     {
  222.     if (XdmClientAuthCompare (existing, client))
  223.     {
  224.         xfree (client);
  225.         return NULL;
  226.     }
  227.     }
  228.     return client;
  229. }
  230.  
  231. int
  232. XdmAddCookie (data_length, data, id)
  233. unsigned short    data_length;
  234. char    *data;
  235. XID    id;
  236. {
  237.     XdmAuthorizationPtr    new;
  238.     unsigned char    *rho_bits, *key_bits;
  239.  
  240.     switch (data_length)
  241.     {
  242.     case 16:            /* auth from files is 16 bytes long */
  243.     rho_bits = (unsigned char *) data;
  244.     key_bits = (unsigned char *) (data + 8);
  245.     break;
  246.     case 8:            /* auth from XDMCP is 8 bytes long */
  247.     rho_bits = rho.data;
  248.     key_bits = (unsigned char *) data;
  249.     break;
  250.     default:
  251.     return 0;
  252.     }
  253.     /* the first octet of the key must be zero */
  254.     if (key_bits[0] != '\0')
  255.     return 0;
  256.     new = (XdmAuthorizationPtr) xalloc (sizeof (XdmAuthorizationRec));
  257.     if (!new)
  258.     return 0;
  259.     new->next = xdmAuth;
  260.     xdmAuth = new;
  261.     bcopy (key_bits, new->key.data, (int) 8);
  262.     bcopy (rho_bits, new->rho.data, (int) 8);
  263.     new->id = id;
  264.     return 1;
  265. }
  266.  
  267. XID
  268. XdmCheckCookie (crypto_length, crypto)
  269. unsigned short    crypto_length;
  270. char    *crypto;
  271. {
  272.     XdmAuthorizationPtr    auth;
  273.     XdmClientAuthPtr    client;
  274.     char        *plain;
  275.  
  276.     plain = (char *) xalloc (crypto_length);
  277.     if (!plain)
  278.     return (XID) -1;
  279.     for (auth = xdmAuth; auth; auth=auth->next) {
  280.     XdmcpDecrypt (crypto, &auth->key, plain, crypto_length);
  281.     if (client = XdmAuthorizationValidate (plain, crypto_length, &auth->rho))
  282.     {
  283.         client->next = xdmClients;
  284.         xdmClients = client;
  285.         xfree (crypto);
  286.         return auth->id;
  287.     }
  288.     }
  289.     xfree (crypto);
  290.     return (XID) -1;
  291. }
  292.  
  293. int
  294. XdmResetCookie ()
  295. {
  296.     XdmAuthorizationPtr    auth, next_auth;
  297.     XdmClientAuthPtr    client, next_client;
  298.  
  299.     for (auth = xdmAuth; auth; auth=next_auth)
  300.     {
  301.     next_auth = auth->next;
  302.     xfree (auth);
  303.     }
  304.     xdmAuth = 0;
  305.     for (client = xdmClients; client; client=next_client)
  306.     {
  307.     next_client = client->next;
  308.     xfree (client);
  309.     }
  310. }
  311.  
  312. XID
  313. XdmToID (crypto_length, crypto)
  314. unsigned short    crypto_length;
  315. char    *crypto;
  316. {
  317.     XdmAuthorizationPtr    auth;
  318.     XdmClientAuthPtr    client;
  319.     char        *plain;
  320.  
  321.     plain = (char *) xalloc (crypto_length);
  322.     if (!plain)
  323.     return (XID) -1;
  324.     for (auth = xdmAuth; auth; auth=auth->next) {
  325.     XdmcpDecrypt (crypto, &auth->key, plain, crypto_length);
  326.     if (client = XdmAuthorizationValidate (plain, crypto_length, &auth->rho))
  327.     {
  328.         xfree (client);
  329.         xfree (crypto);
  330.         return auth->id;
  331.     }
  332.     }
  333.     xfree (crypto);
  334.     return (XID) -1;
  335. }
  336.  
  337. XdmFromID (id, data_lenp, datap)
  338. XID id;
  339. unsigned short    *data_lenp;
  340. char    **datap;
  341. {
  342.     XdmAuthorizationPtr    auth;
  343.  
  344.     for (auth = xdmAuth; auth; auth=auth->next) {
  345.     if (id == auth->id) {
  346.         *data_lenp = 16;
  347.         *datap = (char *) &auth->rho;
  348.         return 1;
  349.     }
  350.     }
  351.     return 0;
  352. }
  353.  
  354. XdmRemoveCookie (data_length, data)
  355. unsigned short    data_length;
  356. char    *data;
  357. {
  358.     XdmAuthorizationPtr    auth, prev;
  359.     XdmAuthKeyPtr    key_bits, rho_bits;
  360.  
  361.     prev = 0;
  362.     switch (data_length)
  363.     {
  364.     case 16:
  365.     rho_bits = (XdmAuthKeyPtr) data;
  366.     key_bits = (XdmAuthKeyPtr) (data + 8);
  367.     break;
  368.     case 8:
  369.     rho_bits = ρ
  370.     key_bits = (XdmAuthKeyPtr) data;
  371.     break;
  372.     default:
  373.     return;
  374.     }
  375.     for (auth = xdmAuth; auth; auth=auth->next) {
  376.     if (XdmcpCompareKeys (rho_bits, &auth->rho) &&
  377.         XdmcpCompareKeys (key_bits, &auth->key))
  378.      {
  379.         if (prev)
  380.         prev->next = auth->next;
  381.         else
  382.         xdmAuth = auth->next;
  383.         xfree (auth);
  384.         return 1;
  385.     }
  386.     }
  387.     return 0;
  388. }
  389.  
  390. #endif
  391.